package cn.honglian.basic.service.impl;

import cn.honglian.basic.config.BussinessException;
import cn.honglian.basic.constant.RegisterCon;
import cn.honglian.basic.dto.FountPhoneLoginDto;
import cn.honglian.basic.service.VerifyCodeService;
import cn.honglian.basic.util.EmailUtil;
import cn.honglian.basic.util.RegexValidateUtil;
import cn.honglian.basic.util.StrUtils;
import cn.honglian.basic.util.VerifyCodeUtils;
import cn.honglian.user.domain.Logininfo;
import cn.honglian.user.domain.User;
import cn.honglian.user.dto.VerificationCodeDto;
import cn.honglian.user.dto.VerifyMailboxCodeDto;
import cn.honglian.user.mapper.LogininfoMapper;
import cn.honglian.user.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class VerifyCodeServiceImpl implements VerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LogininfoMapper logininfoMapper;
    /*
    生成图片验证码返回给前端
     */
    @Override
    public String graph(String imageCodeKey) throws IOException {
        // 随机生成验证码
        String complexRandomString = StrUtils.getComplexRandomString(1);
        String base64 = VerifyCodeUtils.VerifyCode(100, 50, complexRandomString);
        // 将验证码存入redis中
        redisTemplate.opsForValue().set(imageCodeKey, complexRandomString, RegisterCon.IMAGE_CODE_TTL, TimeUnit.MINUTES);
        // 返回base64验证码
        return base64;
    }
    /*
    发送验证码
     */
    @Override
    public void smsCode(VerificationCodeDto dto) {
        if ("regisger".equals(dto.getType())) {
            verify(dto);
            getSmsCode(dto, RegisterCon.REGISTER_PHONE_KEY);
        } else if ("binder".equals(dto.getType())) {
            getSmsCode(dto, RegisterCon.BInDER_PHONE_KEY);
        }

    }

    private void getSmsCode(VerificationCodeDto dto, String key) {
        // 生成随机的验证码
        String smsCode = "";
        String redisSmeCode = (String) redisTemplate.opsForValue().get(key + dto.getPhone());
        if (StringUtils.isNoneBlank(redisSmeCode)) {
            smsCode = redisSmeCode;
        } else {
            smsCode = StrUtils.getComplexRandomString(4);
        }
        log.info("短信验证码为{}:" + smsCode);
        // 将手机验证码存放到redis中
        redisTemplate.opsForValue().set(key + dto.getPhone(), smsCode, RegisterCon.PHONE_CODE_TTL, TimeUnit.MINUTES);
        // 发送验证码
//        SmsUtil.sendUtil(dto.getPhone(),"短信验证码为："+smsCode);
    }

    private void verify(VerificationCodeDto dto) {
        // 参数校验
        if (!RegexValidateUtil.checkPhone(dto.getPhone())) {
            throw new BussinessException("输入的电话号违规，请重新输入");
        }
        if (null == dto.getImageCodeValue()) {
            throw new BussinessException("验证码不能为空");
        }

        // 判断redis中的图片验证码是否与用户传来的一致
        String redisImageCode = (String) redisTemplate.opsForValue().get(dto.getImageCodeKey());
        if (StringUtils.isBlank(redisImageCode) || !dto.getImageCodeValue().equalsIgnoreCase(redisImageCode)) {
            throw new BussinessException("图片验证码不正确");
        }
        // 判断这次的请求时间与上一次是否间隔60秒
        Long ttl = redisTemplate.getExpire(RegisterCon.PHONE_CODE_TTL + dto.getPhone());
        if (null != ttl && ttl > ((RegisterCon.PHONE_CODE_TTL - 1) * 60)) {
            throw new BussinessException("60秒后再获取");
        }
        // 判断这个手机号是否被注册
        User user = userMapper.findByPhone(dto.getPhone());
        if (null != user) {
            throw new BussinessException("赶紧滚去登录");

        }
    }

    /*
        用户邮箱注册发送验证码
     */
    @Override
    public void emailCode(VerifyMailboxCodeDto dto) {
        verifyEmial(dto);
        getEmailCode(dto);
    }

    private void verifyEmial(VerifyMailboxCodeDto dto) {
        // 判断邮箱是否合规
//        if (!RegexValidateUtil.checkEmail(dto.getEmail())){
//            throw new BussinessException("邮箱不合规");
//        }
        if (null != dto.getImageCodeValue()) {
            throw new BussinessException("验证码不能为空");
        }
        // 判断传来的验证码是否与redies中的一致
        String EamilImageCode = (String) redisTemplate.opsForValue().get(dto.getEmailImageCodeKey());
//        System.out.println(EamilImageCode);
//        System.out.println(dto.getImageCodeValue());
        if (StringUtils.isBlank(EamilImageCode) || !dto.getImageCodeValue().equalsIgnoreCase(EamilImageCode)) {
            throw new BussinessException("邮箱验证码不合规");
        }
        // 判断发送请求的时间是否超过规定时间
        Long ttl = redisTemplate.getExpire(RegisterCon.REGISTER_EAMIL_KEY + dto.getEmail());
        if (null != ttl && ttl > ((RegisterCon.PHONE_CODE_TTL - 1) * 60)) {
            throw new BussinessException("60秒后再获取");
        }
        // 判断这个邮箱是否被注册过
        User user = userMapper.findByEmail(dto.getEmail());
        if (null != user) {
            throw new BussinessException("赶紧滚去登录");

        }
    }

    private void getEmailCode(VerifyMailboxCodeDto dto) {
        String emailCode = "";
        String code = (String) redisTemplate.opsForValue().get(RegisterCon.REGISTER_EAMIL_KEY + dto.getEmail());
        if (null != code) {
            emailCode = code;
        } else {
            emailCode = StrUtils.getRandomString(4);
        }
        // 保存到redis中
        redisTemplate.opsForValue().set(RegisterCon.REGISTER_EAMIL_KEY + dto.getEmail(), emailCode, RegisterCon.EAMIL_CODE_TTL, TimeUnit.MINUTES);
        // 发送邮箱验证码
//        EmailUtil.SendEMail("2642986435@qq.com","验证码为：",emailCode,"2642986435@qq.com");
    }

    /*
    用户登录获取验证码
     */
    @Override
    public void smsCodePhone(FountPhoneLoginDto dto) {
        // 参数校验
        if (!RegexValidateUtil.checkPhone(dto.getUserPhone())) {
            throw new BussinessException("输入的电话号违规，请重新输入");
        }
        Logininfo logininfo = logininfoMapper.findByPhone(dto.getUserPhone());
        if (null == logininfo) {
            throw new BussinessException("输入的电话号不存在，请注册");
        }

        // 返回验证码
        String smsCodeLogin = StrUtils.getComplexRandomString(4);
        log.info("短信验证码为{}:" + smsCodeLogin);
        // 将手机验证码存放到redis中
        redisTemplate.opsForValue().set(RegisterCon.REGISTER_PHONE_LOGIN + dto.getUserPhone(), smsCodeLogin, RegisterCon.PHONE_CODE_TTL, TimeUnit.MINUTES);
        // 发送验证码
//        SmsUtil.sendUtil(dto.getPhone(),"短信验证码为："+smsCode);
    }


}
